package com.glSto.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.glSto.domain.PurchaseData;
import com.glSto.domain.PurchaseResponse;
import com.glSto.service.PurchaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class PurchaseServiceImpl implements PurchaseService {

    private static final Logger log = LoggerFactory.getLogger(PurchaseServiceImpl.class);

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 处理采购数据（唯一约束：BANFN+MATNR+EBELN+EINDT）
     */
    @Override
    @Transactional(rollbackFor = Exception.class) // 事务保障：批量处理失败时回滚
    public String handlePurchaseData(String requestBody) throws Exception {
        // 1. 解析JSON（若解析失败直接抛异常，事务回滚）
        PurchaseResponse request = objectMapper.readValue(requestBody, PurchaseResponse.class);
        PurchaseResponse.ImMessage imMessage = request.getIM_MESSAGE();
        List<PurchaseResponse.EtData> etDataList = request.getET_DATA();

        // 2. 先判断明细列表是否为空
        if (etDataList == null || etDataList.isEmpty()) {
            log.info("接收采购数据：明细列表为空，未处理任何数据");
            return "接收成功，但采购明细为空，未存储数据";
        }

        int successCount = 0;
        for (PurchaseResponse.EtData etData : etDataList) {
            // 3. 校验唯一键必传字段（BANFN+MATNR+EBELN+EINDT）
            if (!validateRequiredFields(etData)) {
                log.info("跳过无效采购明细：BANFN={}, MATNR={}, EBELN={}, EINDT={}（唯一键字段为空）",
                        etData.getBANFN(), etData.getMATNR(), etData.getEBELN(), etData.getEINDT());
                continue;
            }

            // 4. 转换为数据库实体
            PurchaseData data = convertToPurchaseData(etData, imMessage);

            // 5. 检查数据是否存在（唯一键：BANFN+MATNR+EBELN+EINDT）
            boolean exists = checkDataExists(etData);

            // 6. 存在则更新，不存在则插入
            if (exists) {
                updateData(data, etData);
                log.info("更新采购明细成功：BANFN={}, MATNR={}, EBELN={}, EINDT={}",
                        etData.getBANFN(), etData.getMATNR(), etData.getEBELN(), etData.getEINDT());
            } else {
                insertData(data);
                log.info("插入采购明细成功：BANFN={}, MATNR={}, EBELN={}, EINDT={}",
                        etData.getBANFN(), etData.getMATNR(), etData.getEBELN(), etData.getEINDT());
            }
            successCount++;
        }

        // 7. 返回处理结果
        log.info("采购数据处理完成：共接收{}条，成功处理{}条", etDataList.size(), successCount);
        return String.format("数据接收成功，共接收 %d 条采购明细，成功处理 %d 条（新增或更新）",
                etDataList.size(), successCount);
    }

    /**
     * 校验唯一键必传字段（BANFN+MATNR+EBELN+EINDT）
     */
    private boolean validateRequiredFields(PurchaseResponse.EtData etData) {
        return etData.getBANFN() != null && !etData.getBANFN().trim().isEmpty()
                && etData.getMATNR() != null && !etData.getMATNR().trim().isEmpty()
                && etData.getEBELN() != null && !etData.getEBELN().trim().isEmpty()
                && etData.getEINDT() != null && !etData.getEINDT().trim().isEmpty();
    }

    /**
     * 检查数据是否存在（固定使用 BANFN+MATNR+EBELN+EINDT 作为唯一键）
     */
    private boolean checkDataExists(PurchaseResponse.EtData etData) {
        String sql = "SELECT COUNT(*) FROM ERP_PURCHASE_DATA " +
                "WHERE BANFN = ? AND MATNR = ? AND EBELN = ? AND EINDT = ?";
        Object[] params = new Object[]{
                etData.getBANFN().trim(),
                etData.getMATNR().trim(),
                etData.getEBELN().trim(),
                etData.getEINDT().trim()
        };

        // 执行查询
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class, params);
        return count != null && count > 0;
    }

    /**
     * 插入新数据（适配 Oracle 数据库：用 SYSDATE 替换 NOW()）
     */
    private void insertData(PurchaseData data) {
        String sql = "INSERT INTO ERP_PURCHASE_DATA (" +
                "BANFN, MATNR, MAKTX, BNFPO, MENGE, EBELN, EBELP, " +
                "MENGE_WEMNG, WEMNG, EINDT, SLFDT, WERKS, LBKUM, " +
                "IM_GUID, SEND_TIME, SENDER, SEND_CFID, RECEIVER, " +
                "RECEIVE_IFID, RECEIVE_METHOD, SEND_SYSTEM_ID, PROXY_ID, " +
                "MANDT, SEND_OPERATOR, SPRAS, CREATE_TIME, UPDATE_TIME" +
                ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, SYSDATE, SYSDATE)";

        jdbcTemplate.update(sql,
                data.getBanfn(),
                data.getMatnr(),
                data.getMaktx(),
                data.getBnfpo(),
                data.getMenge(),
                data.getEbeln(),
                data.getEbelp(),
                data.getMengeWemng(),
                data.getWemng(),
                data.getEindt(),
                data.getSlfdt(),
                data.getWerks(),
                data.getLbkum(),
                data.getImGuid(),
                data.getSendTime(),
                data.getSender(),
                data.getSendCfid(),
                data.getReceiver(),
                data.getReceiveIfid(),
                data.getReceiveMethod(),
                data.getSendSystemId(),
                data.getProxyId(),
                data.getMandt(),
                data.getSendOperator(),
                data.getSpras()
        );
    }

    /**
     * 更新已有数据（唯一键：BANFN+MATNR+EBELN+EINDT）
     */
    private void updateData(PurchaseData data, PurchaseResponse.EtData etData) {
        // 拼接UPDATE SQL的SET部分
        String sql = "UPDATE ERP_PURCHASE_DATA SET " +
                "MAKTX = ?, BNFPO = ?, MENGE = ?, EBELP = ?, " +
                "MENGE_WEMNG = ?, WEMNG = ?, SLFDT = ?, WERKS = ?, LBKUM = ?, " +
                "IM_GUID = ?, SEND_TIME = ?, SENDER = ?, SEND_CFID = ?, " +
                "RECEIVER = ?, RECEIVE_IFID = ?, RECEIVE_METHOD = ?, " +
                "SEND_SYSTEM_ID = ?, PROXY_ID = ?, MANDT = ?, " +
                "SEND_OPERATOR = ?, SPRAS = ?, UPDATE_TIME = SYSDATE " +
                // 唯一键作为WHERE条件
                "WHERE BANFN = ? AND MATNR = ? AND EBELN = ? AND EINDT = ?";

        Object[] params = new Object[]{
                // SET 部分参数
                data.getMaktx(),
                data.getBnfpo(),
                data.getMenge(),
                data.getEbelp(),
                data.getMengeWemng(),
                data.getWemng(),
                data.getSlfdt(),
                data.getWerks(),
                data.getLbkum(),
                data.getImGuid(),
                data.getSendTime(),
                data.getSender(),
                data.getSendCfid(),
                data.getReceiver(),
                data.getReceiveIfid(),
                data.getReceiveMethod(),
                data.getSendSystemId(),
                data.getProxyId(),
                data.getMandt(),
                data.getSendOperator(),
                data.getSpras(),
                // WHERE 部分（唯一键）
                etData.getBANFN().trim(),
                etData.getMATNR().trim(),
                etData.getEBELN().trim(),
                etData.getEINDT().trim()
        };

        jdbcTemplate.update(sql, params);
    }

    /**
     * 转换：请求明细 → 数据库实体
     */
    private PurchaseData convertToPurchaseData(PurchaseResponse.EtData etData, PurchaseResponse.ImMessage imMessage) {
        PurchaseData data = new PurchaseData();

        // 1. 核心字段（含唯一键字段）
        data.setBanfn(etData.getBANFN().trim());
        data.setMatnr(etData.getMATNR().trim());
        data.setMaktx(etData.getMAKTX());
        data.setBnfpo(etData.getBNFPO());
        data.setMenge(etData.getMENGE());
        data.setEbeln(etData.getEBELN().trim());
        data.setEbelp(etData.getEBELP());
        data.setMengeWemng(etData.getMENGE_WEMNG());
        data.setWemng(etData.getWEMNG());
        data.setEindt(etData.getEINDT().trim());
        data.setSlfdt(etData.getSLFDT());
        data.setWerks(etData.getWERKS());
        data.setLbkum(etData.getLBKUM());

        // 2. 消息头字段（判空避免NPE）
        if (imMessage != null) {
            data.setImGuid(imMessage.getIM_GUID());
            data.setSendTime(imMessage.getSEND_TIME());
            data.setSender(imMessage.getSENDER());
            data.setSendCfid(imMessage.getSEND_CFID());
            data.setReceiver(imMessage.getRECEIVER());
            data.setReceiveIfid(imMessage.getRECEIVE_IFID());
            data.setReceiveMethod(imMessage.getRECEIVE_METHOD());
            data.setSendSystemId(imMessage.getSEND_SYSTEM_ID());
            data.setProxyId(imMessage.getPROXY_ID());
            data.setMandt(imMessage.getMANDT());
            data.setSendOperator(imMessage.getSEND_OPERATOR());
            data.setSpras(imMessage.getSPRAS());
        }

        return data;
    }
}